"""
Author: Jian SuiYue kaohx0214@yeah.net
Date: 2025-04-23 00:19:15
LastEditTime: 2025-05-23 14:27:11
FilePath: LibraryManagerStudio/datamodel/types.py
"""

from datetime import datetime
from typing import Optional, Dict, Any, List, TypeVar

from pydantic import BaseModel, EmailStr, Field

from . import BookStatus
from .db import BorrowStatus, UserRole, LogStatus, FriendStatus

T = TypeVar('T')


class Response(BaseModel):
    message: str
    status: bool
    data: Optional[Any] = None


class SocketMessage(BaseModel):
    connection_id: str
    data: Dict[str, Any]
    type: str


# =============== 书籍相关请求/响应模型 ===============


class PageInfo(BaseModel):
    page: int
    size: int


class CategoryBase(BaseModel):
    id: int
    name: str
    description: Optional[str] = None


class BorrowBase(BaseModel):
    uid: int
    book_id: str
    borrowing_time: int


class FriendBase(BaseModel):
    uid: str
    friend_uid: str
    status: FriendStatus


class MessageBase(BaseModel):
    session_id: int
    message: str


# =============== 用户相关请求/响应模型 ===============
# 废弃
class UserRegisterRequest(BaseModel):
    username: str
    password: str
    email: EmailStr
    phone: Optional[str] = None
    avatar_url: Optional[str] = None


class UserLoginRequest(BaseModel):
    id: int
    password: str


class UserProfileResponse(BaseModel):
    uid: int
    username: str
    email: Optional[str] = None
    phone: Optional[str] = None
    avatar_url: Optional[str] = None
    role: UserRole
    is_admin: bool
    created_at: datetime

    class Config:
        from_attributes = True


class UserPasswordChangeRequest(BaseModel):
    old_password: str
    new_password: str


class UserLoginResponse(BaseModel):
    token: str
    user: UserProfileResponse
    expires_at: datetime


class BookUploadRequest(BaseModel):
    title: str
    author: str
    publisher: Optional[str] = None
    isbn: Optional[str] = None
    publication_date: Optional[datetime] = None
    description: Optional[str] = None
    category_id: int = 0  # 默认为0表示未分类，需管理员审核


# =============== 管理员相关请求/响应模型 ===============

class BookApprovalRequest(BaseModel):
    book_id: int
    approved: bool
    reason: Optional[str] = None


class CategoryRequest(BaseModel):
    category_name: str


class UserListResponse(BaseModel):
    users: List[UserProfileResponse]
    total: int


class BookBorrowResponse(BaseModel):
    borrow_id: int
    lender_id: str
    borrower_id: str
    book_id: int
    book_title: str
    borrow_date: datetime
    expected_return_date: datetime
    actual_return_date: Optional[datetime] = None
    status: BorrowStatus

    class Config:
        from_attributes = True


class LogResponse(BaseModel):
    log_id: int
    uid: Optional[str] = None
    username: Optional[str] = None
    status: LogStatus
    message: str
    ip_address: Optional[str] = None
    user_agent: Optional[str] = None
    created_at: datetime

    class Config:
        from_attributes = True


class LogListResponse(BaseModel):
    logs: List[LogResponse]
    total: int


# Update model

class BorrowUpdate(BaseModel):
    id: int
    actual_return_date: datetime
    status: BorrowStatus


class CategoryUpdate(BaseModel):
    id: int
    name: Optional[str] = None
    description: Optional[str] = None


class FriendUpdate(BaseModel):
    id: int
    uid: int
    friend_uid: int
    status: FriendStatus


class WxLoginRequest(BaseModel):
    code: str
    encryptedData: str
    iv: str


class LogResponse(BaseModel):
    """日志响应模型"""
    logs: List[Dict[str, Any]] = Field(..., description="日志列表")
    total: int = Field(..., description="总日志数")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页条数")
    total_pages: int = Field(..., description="总页数")


class LogDatesResponse(BaseModel):
    """日志日期列表响应模型"""
    dates: Dict[str, List[Dict[str, Any]]] = Field(..., description="可用的日志日期")


class UserDataResponse(BaseModel):
    id: int
    username: int
    cover: int
    description: int


class FriendDataResponse(BaseModel):
    uid: int
    friend_uid: int
    status: FriendStatus


class BookResponse(BaseModel):
    id: int
    upload_username: str
    cover: int
    isbn: int
    author: int
    description: int
    category_name: str
    status: BookStatus


class UserLoginResp(BaseModel):
    uid: int
    token: str
    isNewUser: bool
    avatarUrl: Optional[str] = None
    nickName: Optional[str] = None


class UserUpdateData(BaseModel):
    username: Optional[str] = None
    password: Optional[str] = None
    description: Optional[str] = None
    is_admin: Optional[bool] = None
